﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using SYcwpb.Models;
using System.Collections.ObjectModel;
using SYcwpb.Commands;
using System.Windows;
using System.Windows.Input;
using SYcwpb.Access;
using SYcwpb.Views;
using SYcwpb.Helpers;
using System.Text.RegularExpressions;
using System.IO;
using System.Windows.Threading;
using System.Data;
using System.Net;
using System.Threading;
using System.Web;
using System.Configuration;

namespace SYcwpb.ViewModels
{
    class LoginViewModel : ViewModelBase, IDataErrorInfo
    {
        private LoginView _view = null;

        private ICommand _loginCommand;
        private ICommand _closeCommand;

        private LoginModel _loginModel = LoginModel.CreateLoginModel();
        private ILoginAccess _loginAccess = new SimpleLoginAccess();
        private DepartmentAccess _departmentAccess = new DepartmentAccess();
        public bool isLogining = false;


        private string[] _lineOption;
        private ObservableCollection<Department> _departmentList;

        private string headImgNativePath;
        private string headImgSourcePath;

        public Thread UpdateHeadImageThread = null;

        public string UserID
        {
            get { return _loginModel.UserID; }
            set
            {
                if (_loginModel.UserID == value)
                    return;

                _loginModel.UserID = value;

                OnPropertyChanged("UserID");
            }
        }

        public string PasWrd
        {
            get { return _loginModel.PasWrd; }
            set
            {
                if (_loginModel.PasWrd == value)
                    return;

                _loginModel.PasWrd = value;

                OnPropertyChanged("PasWrd");
            }
        }

        public string Line
        {
            get { return _loginModel.Line; }
            set
            {
                if (_loginModel.Line == value)
                    return;

                _loginModel.Line = value;

                OnPropertyChanged("Line");
            }
        }

        public string[] LineOption
        {
            get
            {
                if (null == _lineOption)
                {
                    _lineOption = new string[]
                    {
                        "1",
                        "2"
                    };
                }

                return _lineOption;
            }
        }

        public ObservableCollection<Department> DepartmentList
        {
            get
            {
                return _departmentList;
            }
            set
            {
                _departmentList = value;

                OnPropertyChanged("DepartmentList");
            }
        }

        private Department _depart = Department.CreateDepartment();
        public Department Depart
        {
            get { return _depart; }
            set
            {
                _depart = value;

                if (_depart.ID == _loginModel.Depart)
                    return;

                _loginModel.Depart = _depart.ID;
                _loginModel.DepartName = _depart.Name;

                OnPropertyChanged("Depart");
            }
        }

        private double _prosbarValue;
        public double ProsbarValue
        {
            get { return _prosbarValue; }
            set
            {
                _prosbarValue = value;

                OnPropertyChanged("ProsbarValue");
            }
        }

        public Visibility _updateContentVisiblity = Visibility.Collapsed;
        public Visibility UpdateContentVisiblity
        {
            get { return _updateContentVisiblity; }
            set
            {
                _updateContentVisiblity = value;

                OnPropertyChanged("UpdateContentVisiblity");
            }
        }

        public ICommand LoginCommand
        {
            get
            {
                if (null == _loginCommand)
                {
                    _loginCommand = new RelayCommands(
                        Para => this.Login(),
                        Para => this.CanLogin()
                        );
                }
                return _loginCommand;
            }
        }

        public ICommand CloseCommand
        {
            get
            {
                if (null == _closeCommand)
                {
                    _closeCommand = new RelayCommands(para => this.Close(), para => this.CanClose());
                }
                return _closeCommand;
            }
        }

        public string Error
        {
            get { return null; }
        }

        public string this[string columnName]
        {
            get
            {
                string error = null;
                switch (columnName)
                {
                    case "UserID":
                        error = ValidateUserID();
                        break;
                }
                return error;
            }
        }

        private string ValidateUserID()
        {
            string error = null;
            if (string.IsNullOrEmpty(UserID))
            {
                error = "请输入工号";
            }
            else if (!Regex.IsMatch(this.UserID, @"^\d+$"))
            {
                error = "请使用数字工号登录";
            }
            return error;
        }

        public LoginViewModel(LoginView view)
        {
            _view = view;

            InitDepartmentList();

            UpdateHeadImageThread = new Thread(new ThreadStart(this.UpdateHeadImage));
            UpdateHeadImageThread.SetApartmentState(ApartmentState.STA);
            UpdateHeadImageThread.IsBackground = true;
        }

        private void InitDepartmentList()
        {
            DepartmentList = _departmentAccess.GetDepartmentList();
        }

        private void Close()
        {
            _view.Dispatcher.Invoke(new Action(_view.Close), null);
        }

        private bool CanClose()
        {
            return !isLogining;
        }

        private bool CanLogin()
        {
            return string.IsNullOrEmpty(ValidateUserID()) && !string.IsNullOrEmpty(PasWrd);
                //&& !string.IsNullOrEmpty(Depart.Name) && !string.IsNullOrEmpty(Line) && !isLogining;
            //return true;
        }

        private void Login()
        {
           string mode=ConfigurationManager.AppSettings["Mode"].ToString();
           LoginResultType result;
           if (mode=="Release")
           {
               result = _loginAccess.CheckUserExistMySql(ref _loginModel);
                
           }
               else
	       {
               result = _loginAccess.CheckUserExist(ref _loginModel);
	        }         
            Line = _loginModel.Line;
            foreach (var item in DepartmentList)
            {
                if (item.Name == _loginModel.PostName)
                    Depart = item;
            }

            switch (result)
            {
                case LoginResultType.NoOne:
                    MessageBoxHelper.ShowError("登录失败！此用户不存在或职位、线路与用户不匹配");
                    break;
                case LoginResultType.PasWrdError:
                    MessageBoxHelper.ShowError("登录失败！用户密码错误！");
                    break;
                case LoginResultType.NotInSqlServer:
                    MessageBoxHelper.ShowError("登录失败！SqlServer数据中不存在此用户！");
                    break;
                case LoginResultType.Success:

                    CONSTDATA.UserModel = _loginModel;  //初始化登录用户的全局变量

                    if (null != UpdateHeadImageThread)
                    {
                        UpdateContentVisiblity = Visibility.Visible;
                        UpdateHeadImageThread.Start();
                        UpdateHeadImageThread.IsBackground = true;

                        isLogining = true;
                    }
                    else
                    {

                        this.Close();
                    }
                    break;
            }
            //           


        }

        private void CheckHeadImageNativePath()
        {
            IniFileHelper iniFileHelper = new IniFileHelper("HeadImagePathConfig.ini");
            headImgNativePath = iniFileHelper.ReadString("HeadImagePath", "NativePath", "headInmages/");
            headImgSourcePath = iniFileHelper.ReadString("HeadImagePath", "SourcePath", "");

            if (!headImgNativePath.EndsWith("\\"))
                headImgNativePath += "\\";

            if (!headImgSourcePath.EndsWith("\\"))
                headImgSourcePath += "\\";

            if (!Directory.Exists(headImgNativePath))
            {
                Directory.CreateDirectory(headImgNativePath);
            }
        }

        private void UpdateHeadImage()
        {
            //检查存储头像的本地路径
            CheckHeadImageNativePath();

            //读取属于同一线路的司机信息
            DataTable dtUserHeadImgInfo = _loginAccess.GetUserHeadImgInfo(CONSTDATA.UserModel.Line);

            int error = -1;

            //逐条记录处理
            for (int i = 0; i < dtUserHeadImgInfo.Rows.Count; i++)
            {
                string user_id = dtUserHeadImgInfo.Rows[i]["user_name"].ToString();                          //司机工号
                string user_headImgMD5 = dtUserHeadImgInfo.Rows[i]["user_headImgMD5"].ToString();          //最新头像的md5
                string user_img = dtUserHeadImgInfo.Rows[i]["user_img"].ToString();                        //最新头像的url

                if (string.IsNullOrEmpty(user_headImgMD5) || string.IsNullOrEmpty(user_img))
                {
                    continue;
                }
                //判断本地是否有该司机头像，没有则从服务器上下载
                if (!File.Exists(headImgNativePath + user_id + ".jpg"))
                {
                    //从服务器上面下载头像
                    downloadDriverHeadImg(headImgSourcePath + user_img, user_id, ref error);
                    if (error == 0) //无法连接服务器
                    {
                        MessageBoxHelper.ShowError("更新司机头像信息失败：无法连接远程服务器");
                        break;
                    }

                }

                //从服务器下载头像后，再次判断本地是否有该司机头像，没有则设置为默认头像
                //默认头像使用名为defaultHeadImage.jpg的图片文件
                if (!File.Exists(headImgNativePath + user_id + ".jpg"))
                {
                    File.Copy("Images/defaultHeadImage.jpg", headImgNativePath + user_id + ".jpg");

                }

                //获取本地头像的md5
                string nativeMD5 = md5_hash(headImgNativePath + user_id + ".jpg");

                //比较最新头像的md5和本地头像的md5
                if (!String.Equals(user_headImgMD5, nativeMD5))
                {
                    //md5不等，说明头像被更新，下载新头像
                    if (!downloadHeadImg(headImgSourcePath + user_img, user_id, ref error))
                    {
                        if (error == 0) //无法连接服务器
                        {
                            MessageBoxHelper.ShowError("更新司机头像信息失败：无法连接远程服务器");
                            break;
                        }
                    }
                }

                ProsbarValue = i * 100 / dtUserHeadImgInfo.Rows.Count;
            }

            File.Delete("temp.jpg");

            this.Close();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <param name="user_id"></param>
        /// <param name="err">0:无法连接远程服务器</param>
        /// <returns></returns>
        private bool downloadHeadImg(string url, string user_id, ref int err)
        {
            bool result = true;

            HttpWebRequest request = null;
            HttpWebResponse response = null;
            Stream stream = null;
            FileStream fs = null;
            try
            {
                //return true;
                //下载新头像文件
                request = (HttpWebRequest)WebRequest.Create(url);
                //request.Timeout = 1000;    //1秒超时
                response = (HttpWebResponse)request.GetResponse();
                stream = response.GetResponseStream();
                long sl = response.ContentLength;

                int bufferSize = 1024;
                byte[] buffer = new byte[bufferSize];
                int count = 0;

                //下载的新头像文件先存储为temp.jpg
                fs = new FileStream("temp.jpg", FileMode.Create);
                while ((count = stream.Read(buffer, 0, bufferSize)) > 0)
                {
                    fs.Write(buffer, 0, count);
                }
                fs.Flush();
                fs.Close();

                //替换掉旧头像
                File.Copy("temp.jpg", headImgNativePath + user_id + ".jpg", true);
            }
            catch (WebException ex)
            {
                if (ex.Status == WebExceptionStatus.ConnectFailure)
                {
                    result = false;

                    err = 0;
                }
            }
            catch (Exception e)
            {

                result = false;
            }
            finally
            {
                if (stream != null)
                {
                    stream.Close();
                }

                if (fs != null)
                {
                    fs.Close();
                }
                if (request != null)
                {
                    request.Abort();
                }
                if (response != null)
                {
                    response.Close();
                }
            }

            return result;
        }

        /// <summary>
        /// 下载司机的头像，本地没有司机头像时使用
        /// </summary>
        /// <param name="url"></param>
        /// <param name="user_id"></param>
        /// <param name="err"></param>
        private void downloadDriverHeadImg(string url, string user_id, ref int err)
        {
            HttpWebRequest request = null;
            HttpWebResponse response = null;
            Stream stream = null;
            FileStream fs = null;
            try
            {
                //下载新头像文件
                request = (HttpWebRequest)WebRequest.Create(url);
                //request.Timeout = 1000;    //1秒超时
                  response = (HttpWebResponse)request.GetResponse();
                stream = response.GetResponseStream();
                long sl = response.ContentLength;

                int bufferSize = 1024;
                byte[] buffer = new byte[bufferSize];
                int count = 0;

                //下载的头像文件
                fs = new FileStream(headImgNativePath + user_id + ".jpg", FileMode.Create);
                while ((count = stream.Read(buffer, 0, bufferSize)) > 0)
                {
                    fs.Write(buffer, 0, count);
                }
                fs.Flush();
                fs.Close();

            }
            catch (WebException ex)
            {
                if (ex.Status == WebExceptionStatus.ConnectFailure)
                {
                    err = 0;
                }
            }
            catch (Exception e)
            {
            }
            finally
            {
                if (stream != null)
                {
                    stream.Close();
                }

                if (fs != null)
                {
                    fs.Close();
                }
                if (request != null)
                {
                    request.Abort();
                }
                if (response != null)
                {
                    response.Close();
                }
            }
        }

        private string md5_hash(string path)
        {
            string result;
            FileStream get_file = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);

            try
            {
                System.Security.Cryptography.MD5CryptoServiceProvider get_md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
                byte[] hash_byte = get_md5.ComputeHash(get_file);
                result = System.BitConverter.ToString(hash_byte);
                result = result.Replace("-", "");
                get_md5.Clear();
            }
            catch (Exception e)
            {
                result = e.ToString();
            }
            finally
            {
                get_file.Close();
            }

            return result;
        }
    }
}
